using UnityEngine;
using UnityEditor;
using System.Collections;

/// <summary>
/// A helper class providing some convenient methods to do small Editor tasks
/// </summary>
public static class EditorTools
{
	/// <summary>
	/// Draw a half-transparent seperator of 4 pixel height
	/// </summary>
	public static void drawSeperator ()
	{
		GUILayout.Space (12);
		
		if (Event.current.type == EventType.Repaint)
		{
			Texture2D tex = blackTexture;
			Rect rect = GUILayoutUtility.GetLastRect ();
			Color guiColor = GUI.color;
			GUI.color = new Color (0, 0, 0, 0.25f);
			GUI.DrawTexture (new Rect (0, rect.yMin + 6, Screen.width, 4), tex);
			GUI.DrawTexture (new Rect (0, rect.yMin + 6, Screen.width, 1), tex);
			GUI.DrawTexture (new Rect (0, rect.yMin + 9, Screen.width, 1), tex);
			GUI.color = guiColor;
		}
	}
	
	/// <summary>
	/// Change a texture's import settings to disable mapmapping, enable readable and
	/// change texture format to RGBA32, npot scale to none, filter mode to Point, max
	/// texture size to 4096.
	/// </summary>
	/// <returns>
	/// True if import settings are changed successfully, otherwise false.
	/// </returns>
	/// <param name='path'>
	/// Path of the target texture.
	/// </param>
	public static bool makeTextureReadable (string path)
	{
		if (string.IsNullOrEmpty (path)) return false;
		
		TextureImporter ti = AssetImporter.GetAtPath (path) as TextureImporter;
		if (ti == null) return false;
		
		TextureImporterSettings settings = new TextureImporterSettings ();
		ti.ReadTextureSettings (settings);
		
		settings.mipmapEnabled = false;
		settings.readable = true;
		settings.filterMode = FilterMode.Point;
		settings.wrapMode = TextureWrapMode.Clamp;
		settings.npotScale = TextureImporterNPOTScale.None;
		settings.textureFormat = TextureImporterFormat.RGBA32;
		settings.maxTextureSize = 4096;
		
		ti.SetTextureSettings (settings);
		AssetDatabase.ImportAsset (path, ImportAssetOptions.ForceUpdate);
		return true;
	}
	
	/// <summary>
	/// Change a texture's import settings to disable mapmapping, diable readable,
	/// change max texture size to 4096, texture format to ARGB32 to get a high
	/// resolution, set npot scale to nearest power of 2, set filter mode to
	/// point and wrap mode to clamp.
	/// </summary>
	/// <returns>
	/// True if import settings are changed successfully, otherwise false.
	/// </returns>
	/// <param name='path'>
	/// IPath of the target texture.
	/// </param>
	public static bool makeTextureAsAtlas (string path)
	{
		if (string.IsNullOrEmpty (path)) return false;
		
		TextureImporter ti = AssetImporter.GetAtPath (path) as TextureImporter;
		if (ti == null) return false;
		
		TextureImporterSettings settings = new TextureImporterSettings ();
		ti.ReadTextureSettings (settings);
		
		settings.mipmapEnabled = false;
		settings.readable = false;
		settings.maxTextureSize = 4096;
		settings.textureFormat = TextureImporterFormat.ARGB32;
		settings.filterMode = FilterMode.Point;
		settings.wrapMode = TextureWrapMode.Clamp;
		settings.npotScale = TextureImporterNPOTScale.ToNearest;
		
		ti.SetTextureSettings (settings);
		AssetDatabase.ImportAsset (path, ImportAssetOptions.ForceUpdate);
		return true;
	}
	
	/// <summary>
	/// Build <paramref name="mainAsset"/> into asset bundle. The result path
	/// will be exactly the same as asset-path of <paramref name="mainAsset"/>, 
	/// but in StreamingAssets directory and with a extension name of ".unity3d" 
	/// </summary>
	/// <returns>
	/// True when build successfully, otherwise false
	/// </returns>
	/// <param name='mainAsset'>
	/// Asset to be built.
	/// </param>
	/// <param name='options'>
	/// Build options.
	/// </param>
	/// <param name='buildTarget'>
	/// Build target platform.
	/// </param>
	public static bool buildAssetBundle (UnityEngine.Object mainAsset, 
		BuildAssetBundleOptions options, BuildTarget buildTarget)
	{
		string streamingPath = prepareStreamingAssetPath (mainAsset, true);
		bool ret = BuildPipeline.BuildAssetBundle (mainAsset, null, streamingPath, options, buildTarget);
		if (ret) AssetDatabase.Refresh ();
		return ret;
	}
	
	/// <summary>
	/// Get path of asset bundle built from <paramref name="srcObject"/>, the 
	/// result path will be like "SteamingAssets/[assetPathOfSrcObject]" with 
	/// extension name to "unity3d". If the directory of result path will be 
	/// created if it doesn't exist and <paramref name="createDir"/> is true,  
	/// </summary>
	/// <returns>
	/// The streaming asset path of the generated asset bundle.
	/// </returns>
	/// <param name='srcObject'>
	/// Object which will be build into asset bundle.
	/// </param>
	public static string prepareStreamingAssetPath (UnityEngine.Object srcObject, bool createDir)
	{
		string srcPath = AssetDatabase.GetAssetPath (srcObject);
		
		int fileNameIndex = srcPath.IndexOf (srcObject.name);
		
		string targetDirPath = Application.streamingAssetsPath + 
			srcPath.Substring ("Assets".Length, fileNameIndex - "Assets".Length);
		
		if (createDir && !System.IO.Directory.Exists (targetDirPath))
		{
			System.IO.Directory.CreateDirectory (targetDirPath);
		}
		
		string filePath = targetDirPath + srcObject.name + ".unity3d";
		
		return filePath;
	}
	
	static Texture2D blackTexture 
	{
		get 
		{
			if (m_blackTex == null)
			{
				m_blackTex = new Texture2D (1, 1);
				m_blackTex.SetPixel (0, 0, Color.black);
				m_blackTex.Apply ();
			}
			return m_blackTex;
		}
	}
	
	static Texture2D m_blackTex;
}
